#include "stdafx.h"
#include "CppUnitTest.h"

#include "MxPluginManager\MxPluginManager1.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputePluginLib.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageCompute.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputeFnDef.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputeFn.h"

#include "..\..\PublicInterfaces\PluginICPopenCV\OCV-Dev-ProductID.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace PluginICPopenCVTest
{
	TEST_CLASS(SnakeImageTest)
	{
	private:
		MxPluginManager			*_pluginMngr;
		MxPluginLib				*_plugin;
		IImageComputePluginLib	*_lib;
		IImageCompute		    *_icp;
		IImageComputeFnDef		*_fnDef;
		IImageComputeFn			*_fn;

	public:

		TEST_METHOD_INITIALIZE(SnakeImgInit)
		{
			_pluginMngr = new MxPluginManager();
			if (_pluginMngr->RefreshPluginsInRootFolder(SID_ImageProc, true) == true)
			{
				if ((_plugin = _pluginMngr->GetPlugin(PRODID_PluginICPopenCV)) != nullptr)
				{
					if ((_lib = static_cast<IImageComputePluginLib *>(_plugin->CreateClassInstance(IImageComputePluginLibIID::Guid()))) != nullptr)
					{
						if((_icp = _lib->GetIImageCompute()) != nullptr)
						{
							GUID fnID = MxGUID::ConvertFromString("{66D56DA2-0DD0-4617-9036-61FBC78BF0A0}");
							_fnDef =_icp->GetIImageComputeFnDef(fnID);
							_fn =_icp->GetIImageComputeFn(fnID);
						}
					}
				}
			}
		}

		TEST_METHOD_CLEANUP(SnakeImgDeinit)
		{
			if(_fn != nullptr)
				_fn->DestroyPtr();
			_fn = nullptr;

			if(_fnDef!= nullptr)
				_fnDef->DestroyPtr();
			_fnDef = nullptr;

			if(_icp != nullptr)
				_icp->DestroyPtr();
			_icp = nullptr;

			if(_lib != nullptr)
				_lib->DestroyPtr();
			_lib = nullptr;

			if (_pluginMngr != nullptr)
				delete _pluginMngr;
			_pluginMngr = nullptr;
		}
		
		TEST_METHOD(SnakeImgCreateTest)
		{
			Assert::IsNotNull(_fnDef);
			Assert::IsTrue(_fnDef->IsValid());

			Assert::IsNotNull(_fn);
			Assert::IsTrue(_fn->IsValid());
		}

		TEST_METHOD(SnakeImgFnDefParamsTest)
		{
			Assert::IsNotNull(_fnDef);
			Assert::IsTrue(_fnDef->IsValid());

			Assert::AreEqual("SnakeImg", _fnDef->GetLabel());
			Assert::AreEqual("Find boundary of the image using Snake Algorithm", _fnDef->GetDescription());
			Assert::AreEqual("Common", _fnDef->GetToolboxClass());
			Assert::AreEqual("Snake", _fnDef->GetToolboxLabel());
			Assert::AreEqual(5, _fnDef->GetToolboxIconClassOffset());

			Assert::AreEqual(12, _fnDef->GetParamCount(IImageComputeFnDef::Direction::Input));
			Assert::AreEqual(3, _fnDef->GetParamCount(IImageComputeFnDef::Direction::Output));
			Assert::AreEqual(2, _fnDef->GetParamCount(IImageComputeFnDef::Direction::IO));

			Assert::AreEqual("StopProc", _fnDef->GetParamName(IImageComputeFnDef::Direction::IO, 0));
			Assert::AreEqual("ImageRef", _fnDef->GetParamName(IImageComputeFnDef::Direction::IO, 1));
			Assert::AreEqual("RootFolder", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 0));
			Assert::AreEqual("IJC", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 1));
			Assert::AreEqual("IJF", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 2));
			Assert::AreEqual("Alpha", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 3));
			Assert::AreEqual("Beta", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 4));
			Assert::AreEqual("Gamma", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 5));
			Assert::AreEqual("NeighborHt", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 6));
			Assert::AreEqual("NeighborWd", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 7));
			Assert::AreEqual("MaxIter", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 8));
			Assert::AreEqual("Epsilon", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 9 ));
			Assert::AreEqual("InitPts", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 10));
			Assert::AreEqual("Gradient", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 11));
			Assert::AreEqual("ResPts", _fnDef->GetParamName(IImageComputeFnDef::Direction::Output, 0));
			Assert::AreEqual("RotRect", _fnDef->GetParamName(IImageComputeFnDef::Direction::Output, 1));
			Assert::AreEqual("Score", _fnDef->GetParamName(IImageComputeFnDef::Direction::Output, 2));


			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("StopProc")) == IImageComputeFnDef::ParamType::Bool);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("RootFolder")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("IJC")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("IJF")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("ImageRef")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("Alpha")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("Beta")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("Gamma")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("NeighborHt")) == IImageComputeFnDef::ParamType::Integer);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("NeighborWd")) == IImageComputeFnDef::ParamType::Integer);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("MaxIter")) == IImageComputeFnDef::ParamType::Integer);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("Epsilon")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("InitPts")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("Gradient")) == IImageComputeFnDef::ParamType::Integer);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("ResPts")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("RotRect")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("Score")) == IImageComputeFnDef::ParamType::Double);

			Assert::IsFalse(_fnDef->IsParamValMinSet("RootFolder"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("RootFolder"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("IJC"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("IJC"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("IJF"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("IJF"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("ImageRef"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("ImageRef"));

			Assert::IsFalse(_fnDef->IsParamValMinSet("Alpha"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("Alpha"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("Beta"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("Beta"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("Gamma"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("Gamma"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("NeighborHt"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("NeighborHt"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("NeighborWd"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("NeighborWd"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("MaxIter"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("MaxIter"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("Epsilon"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("Epsilon"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("InitPts"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("InitPts"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("Gradient"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("Gradient"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("ResPts"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("ResPts"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("RotRect"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("RotRect"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("Score"));					//bug in mapping double vars when min and max set
			Assert::IsFalse(_fnDef->IsParamValMaxSet("Score"));					//bug in mapping double vars when min and max set

			Assert::AreEqual(0, _fnDef->GetParamValMin("NeighborHt"));
			Assert::AreEqual(0, _fnDef->GetParamValMin("NeighborWd"));
			Assert::AreEqual(0, _fnDef->GetParamValMin("MaxIter"));

			
		//	Assert::AreEqual(-1.0, _fnDef->GetParamDoubleValMin("Score"));		//bug in mapping double vars when min and max set
		//	Assert::AreEqual(100.0, _fnDef->GetParamDoubleValMax("Score"));		//bug in mapping double vars when min and max set


			Assert::AreEqual("no", _fnDef->GetParamDefaultVal("StopProc"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("RootFolder"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("IJC"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("IJF"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("ImageRef"));
			Assert::AreEqual("0.4", _fnDef->GetParamDefaultVal("Alpha"));
			Assert::AreEqual("0.2", _fnDef->GetParamDefaultVal("Beta"));
			Assert::AreEqual("1.0", _fnDef->GetParamDefaultVal("Gamma"));
			Assert::AreEqual("3", _fnDef->GetParamDefaultVal("NeighborHt"));
			Assert::AreEqual("3", _fnDef->GetParamDefaultVal("NeighborWd"));
			Assert::AreEqual("1000", _fnDef->GetParamDefaultVal("MaxIter"));
			Assert::AreEqual("0.1", _fnDef->GetParamDefaultVal("Epsilon"));
			Assert::AreEqual("ArrayInts:0;", _fnDef->GetParamDefaultVal("InitPts"));
			Assert::AreEqual("0", _fnDef->GetParamDefaultVal("Gradient"));
			Assert::AreEqual("ArrayInts:0;", _fnDef->GetParamDefaultVal("ResPts"));
			Assert::AreEqual("ArrayInts:0;", _fnDef->GetParamDefaultVal("RotRect"));
			Assert::AreEqual("-1.0", _fnDef->GetParamDefaultVal("Score"));

			Assert::AreEqual("Stop", _fnDef->GetParamLabel("StopProc"));
			Assert::AreEqual("Root folder", _fnDef->GetParamLabel("RootFolder"));
			Assert::AreEqual("IJC id", _fnDef->GetParamLabel("IJC"));
			Assert::AreEqual("IJF id", _fnDef->GetParamLabel("IJF"));
			Assert::AreEqual("ImageRef", _fnDef->GetParamLabel("ImageRef"));
			Assert::AreEqual("Alpha", _fnDef->GetParamLabel("Alpha"));
			Assert::AreEqual("Beta", _fnDef->GetParamLabel("Beta"));
			Assert::AreEqual("Gamma", _fnDef->GetParamLabel("Gamma"));
			Assert::AreEqual("Neighbor Ht", _fnDef->GetParamLabel("NeighborHt"));
			Assert::AreEqual("Neighbor Wd", _fnDef->GetParamLabel("NeighborWd"));
			Assert::AreEqual("Max Iter", _fnDef->GetParamLabel("MaxIter"));
			Assert::AreEqual("Epsilon", _fnDef->GetParamLabel("Epsilon"));
			Assert::AreEqual("Initial Pts", _fnDef->GetParamLabel("InitPts"));
			Assert::AreEqual("Gradient", _fnDef->GetParamLabel("Gradient"));
			Assert::AreEqual("Result Pts", _fnDef->GetParamLabel("ResPts"));
			Assert::AreEqual("RotRect", _fnDef->GetParamLabel("RotRect"));
			Assert::AreEqual("Score", _fnDef->GetParamLabel("Score"));

			Assert::AreEqual("Do not process this step or any further steps", _fnDef->GetParamDesc("StopProc"));
			Assert::AreEqual("folder for project root", _fnDef->GetParamDesc("RootFolder"));
			Assert::AreEqual("GUID for job collection", _fnDef->GetParamDesc("IJC"));
			Assert::AreEqual("GUID for job file", _fnDef->GetParamDesc("IJF"));
			Assert::AreEqual("name of input image in ImageFolder without filetype", _fnDef->GetParamDesc("ImageRef"));
		}

		TEST_METHOD(SnakeImgRunTest)
		{
			Assert::IsNotNull(_fn);
			Assert::IsTrue(_fn->IsValid());

			Assert::IsTrue(_fn->InitCall(0, ".bmp", true, true));

			Assert::IsTrue(_fn->SetParamBool("StopProc", false));
			Assert::IsTrue(_fn->SetParamStr("RootFolder", "..\\..\\..\\TestImages"));
			Assert::IsTrue(_fn->SetParamStr("IJC", "IJC"));
			Assert::IsTrue(_fn->SetParamStr("IJF", "IJF"));
			Assert::IsTrue(_fn->SetParamStr( "ImageRef", "SnakeTest"));
			Assert::IsTrue(_fn->SetParamDouble("Alpha", 0.2));
			Assert::IsTrue(_fn->SetParamDouble("Beta", 0.4));
			Assert::IsTrue(_fn->SetParamDouble("Gamma", 1.0));
			Assert::IsTrue(_fn->SetParamInt("NeighborHt", 1));
			Assert::IsTrue(_fn->SetParamInt("NeighborWd", 1));
			Assert::IsTrue(_fn->SetParamInt("MaxIter", 1000));
			Assert::IsTrue(_fn->SetParamDouble("Epsilon", 0.1));
			Assert::IsTrue(_fn->SetParamStr( "InitPts", "ArrayInts:170;489;231;556;332;599;463;599;537;577;575;522;602;463;611;385;588;307;527;244;425;220;332;225;231;257;193;348;"));
			Assert::IsTrue(_fn->SetParamInt("Gradient", 0));

			Assert::IsTrue(_fn->ValidateCall());
			Assert::AreEqual(28, _fn->ArrayIntsGetSize(_fn->GetParamStr("InitPts")));
			Assert::IsTrue(_fn->DoCall());

			Assert::AreEqual(28, _fn->ArrayIntsGetSize(_fn->GetParamStr("ResPts")));
			Assert::AreEqual("ArrayInts:170;489;231;556;332;599;463;599;537;577;575;522;602;463;611;385;588;307;527;244;425;220;332;225;231;257;193;348;", _fn->GetParamStr("ResPts"));
			Assert::AreEqual("ArrayInts:390;412;400;453;87;", _fn->GetParamStr("RotRect"));
			Assert::AreEqual(100.0, _fn->GetParamDouble("Score"), 0.01);
		}

	};
}
